package com.wh1200.mybatis.xmlless.model.base

import com.wh1200.mybatis.xmlless.annotations.TestCriteria
import com.wh1200.mybatis.xmlless.annotations.criteria.Criteria
import com.wh1200.mybatis.xmlless.enums.TestType
import com.wh1200.mybatis.xmlless.model.ChooseCriteriaInfo
import com.wh1200.mybatis.xmlless.model.ClassInfo
import com.wh1200.mybatis.xmlless.model.JoinObjectInfo
import org.apache.ibatis.type.TypeHandler
import java.lang.reflect.Type


/**
 *
 * @author 吴昊
 * @date 2024/1/17 21:46
 * @since v0.0.0
 * @version 1.0
 */
interface BaseAnnotatedElementWrapper {

  /**
   * @param exp
   * @return
   */
  fun parseTestCriteria(exp: String): TestCriteria {
    val ifBuilder = StringBuilder()
    var ifEnded = false
    val sqlBuilder = StringBuilder()
    val wordList = exp.split("\\s+".toRegex())
    if (wordList.first().lowercase() !in listOf("if", "when")) {
      throw IllegalArgumentException("表达式必须以if或when开头")
    }
    wordList.drop(1).forEach {
      if (it.lowercase() == "then") {
        ifEnded = true
      } else if (ifEnded) {
        sqlBuilder.append(it).append(" ")
      } else {
        ifBuilder.append(it).append(" ")
      }
    }
    return TestCriteria(ifBuilder.toString().trim(), sqlBuilder.toString().trim())
  }

  /**
   * @return
   */
  fun getUpdate(): String?

  /**
   * @return
   */
  fun getElement(): Any

  /**
   * @return
   */
  fun isNotNull(): Boolean

  /**
   * @return
   */
  fun getName(): String

  /**
   * @return
   */
  fun getType(): BaseClassWrapper

  /**
   * @return
   */
  fun isNotBlank(): Boolean

  /**
   * @return
   */
  fun isNotEmpty(): Boolean

  /**
   * @return
   */
  fun isInsertIgnore(): Boolean

  /**
   * @return
   */
  fun isSelectIgnore(): Boolean

  /**
   * @return
   */
  fun isUpdateIgnore(): Boolean

  /**
   * @return
   */
  fun isAutoGenerateKey(): Boolean

  /**
   * @return
   */
  fun isCount(): Boolean

  /**
   * @return
   */
  fun isJsonMappingProperty(): Boolean

  /**
   * @return
   */
  fun getGenericType(): Type

  /**
   * @return
   */
  fun getSpecificName(): String?

  /**
   * @return
   */
  fun getTypeHandlerName(): String?

  /**
   * @return
   */
  fun getCriteria(): Criteria?

  /**
   * @return
   */
  fun getJoinPropertyList(): List<JoinObjectInfo>

  /**
   * @return
   */
  fun getCustomTypeHandlerClass(): Class<out TypeHandler<*>>?

  /**
   * @return
   */
  fun getChooseCriteria(): ChooseCriteriaInfo

  /**
   * @return
   */
  fun getParameterTestTypeList(): List<TestType>

  /**
   * 对参数不使用<if></if>进行判断
   *
   * @return
   */
  fun isNoIfWrap(): Boolean

  /**
   * @return
   */
  fun isPrimitive(): Boolean

  /**
   * @return
   */
  fun isString(): Boolean

  /**
   * @return
   */
  fun isCollection(): Boolean

  /**
   * @return
   */
  fun getTypeInfo(): ClassInfo {
    return ClassInfo[getType()]
  }

  /**
   * @return
   */
  fun getPropertyMapTo(): String

  fun isVersion(): Boolean
}
